package com.health.service;

import com.health.dto.LoginRequest;
import com.health.dto.RegisterRequest;
import com.health.dto.UpdateUserRequest;
import com.health.dto.UpdatePasswordRequest;
import com.health.dto.UserPageRequest;
import com.health.dto.PageResponse;
import com.health.model.User;
import com.health.model.UserRole;
import com.health.model.UserStatus;
import com.health.repository.UserRepository;
import com.health.validation.UserValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private UserValidator userValidator;
    
    public User register(RegisterRequest request) {
        // 普通用户注册时，强制设置为 USER 角色
        request.setRole(UserRole.USER);
        return createUser(request);
    }
    
    public User login(LoginRequest request) {
        System.out.println("Attempting login with username: " + request.getUsername());
        
        User user = userRepository.findByUsername(request.getUsername())
            .orElseThrow(() -> new RuntimeException("用户名或密码错误"));
            
        System.out.println("Found user: " + user.getUsername());
        System.out.println("User role: " + user.getRole());
        System.out.println("Input password: " + request.getPassword());
        System.out.println("Stored password: " + user.getPassword());
        
        boolean matches = passwordEncoder.matches(request.getPassword(), user.getPassword());
        System.out.println("Raw password matches: " + matches);
        System.out.println("Encoded input password: " + passwordEncoder.encode(request.getPassword()));
        
        if (!matches) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        return user;
    }
    
    public User getUserById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("用户不存在"));
    }
    
    public User updateUser(Long id, UpdateUserRequest request) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 更新用户信息
        if (request.getEmail() != null) {
            user.setEmail(request.getEmail());
        }
        if (request.getPhone() != null) {
            user.setPhone(request.getPhone());
        }
        if (request.getGender() != null) {
            user.setGender(request.getGender());
        }
        
        // 保存并返回更新后的用户信息
        return userRepository.save(user);
    }
    
    public void updatePassword(Long id, UpdatePasswordRequest request) {
        User user = getUserById(id);
        
        // 验证旧密码
        if (!passwordEncoder.matches(request.getOldPassword(), user.getPassword())) {
            throw new RuntimeException("旧密码不正确");
        }
        
        // 更新为新密码
        user.setPassword(passwordEncoder.encode(request.getNewPassword()));
        userRepository.save(user);
    }
    
    public PageResponse<User> getUserList(UserPageRequest request) {
        Pageable pageable = PageRequest.of(
            request.getPage() - 1,
            request.getSize(),
            Sort.by(Sort.Direction.DESC, "createTime")
        );
        
        Specification<User> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (StringUtils.hasText(request.getUsername())) {
                predicates.add(cb.like(root.get("username"), "%" + request.getUsername() + "%"));
            }
            
            if (StringUtils.hasText(request.getEmail())) {
                predicates.add(cb.like(root.get("email"), "%" + request.getEmail() + "%"));
            }
            
            return predicates.isEmpty() ? null : cb.and(predicates.toArray(new Predicate[0]));
        };
        
        Page<User> page = userRepository.findAll(spec, pageable);
        return PageResponse.of(page.getContent(), page.getTotalElements(), 
                             request.getPage(), request.getSize());
    }
    
    public User addUser(RegisterRequest request) {
        // 管理员可以指定用户角色
        return createUser(request);
    }
    
    // 抽取公共的用户创建逻辑
    private User createUser(RegisterRequest request) {
        // 验证请求数据
        userValidator.validateRegisterRequest(request);
        
        // 检查用户名和邮箱是否已存在
        if (userRepository.existsByUsername(request.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        if (userRepository.existsByEmail(request.getEmail())) {
            throw new RuntimeException("邮箱已被使用");
        }
        
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setGender(request.getGender());
        user.setRole(request.getRole());
        
        return userRepository.save(user);
    }
    
    public void updateUserStatus(Long id, UserStatus status) {
        User user = getUserById(id);
        user.setStatus(status);
        userRepository.save(user);
    }
    
    public void deleteUser(Long id) {
        if (!userRepository.existsById(id)) {
            throw new RuntimeException("用户不存在");
        }
        userRepository.deleteById(id);
    }
} 